﻿using com.iot.core.boot.configuration;
using com.iot.core.data;
using com.iot.core.data.entity;
using com.iot.core.infrastructure;
  
using System.Runtime.CompilerServices;
 

namespace com.iot.core.manager.id
{
    public class HtIdManager
    {
        IdWorker worker;
        
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static HtIdManager Create()
        {
            //create NopEngine as engine
            var m= Singleton<HtIdManager>.Instance ?? (Singleton<HtIdManager>.Instance = new HtIdManager());

            var cfg = Singleton<AppSettings>.Instance.Get<IDConfig>();
            m.worker = new IdWorker(cfg.WorkerId, cfg.DataCenterId);

            return m;
        }
        public static HtIdManager Current
        {
            get
            {
                if (Singleton<HtIdManager>.Instance == null)
                {
                    Create();
                }

                return Singleton<HtIdManager>.Instance;
            }
        }
        public static HtIdManager GetInstance()
        {
            return Current;
        }


        public long NextLong()
        {
            return worker.NextId();
        }


        object objDBID = new object();
        public long NextDBID(string name)
        {
            lock (objDBID)
            {
                var service = EngineContext.Current.Resolve<IBaseService<HtTbid>>();
                var m= service.GetAll().Where(a => a.Tname == name).FirstOrDefault();
                if (m.IncludeDt)
                { 
                    if (m.DayRestart)
                    {
                        if (m.CurrentDt != DateTime.Now.ToString("yyyyMMdd") )
                        {
                            m.CurrentDt = DateTime.Now.ToString("yyyyMMdd");
                            m.Idv = 0;
                        }
                    }
                    else
                    {
                        
                    }
                    m.Idv++;
                    long r =Convert.ToInt64( long.Parse(DateTime.Now.ToString("yyyyMMdd")) * Math.Pow(10, m.IdLength)+m.Idv);
                    service.Update(m);
                    return r;
                }
                else
                {
                    m.Idv++;
                    service.SaveChagnes();
                    return m.Idv;
                }
            }
        }
        public List<long> NextDBIDS(string name,int len)
        {
            var l = new List<long>();
            lock (objDBID)
            {
                var service = EngineContext.Current.Resolve<IBaseService<HtTbid>>();
                var m = service.GetAll().Where(a => a.Tname == name).FirstOrDefault();
                if (m.IncludeDt)
                {
                    if (m.DayRestart)
                    {
                        if (m.CurrentDt != DateTime.Now.ToString("yyyyMMdd"))
                        {
                            m.CurrentDt = DateTime.Now.ToString("yyyyMMdd");
                            m.Idv = 0;
                           
                        }
                    }
                    
                    for (var i = 0; i < len; i++)
                    {
                        m.Idv++;
                        long r = Convert.ToInt64(long.Parse(DateTime.Now.ToString("yyyyMMdd")) * Math.Pow(10, m.IdLength) + m.Idv);                       
                        l.Add(r);
                    }


                    service.Update(m);
                    return l;
                }
                else
                {
                    for (var i = 0; i < len; i++)
                    {
                        m.Idv++;
                        l.Add(m.Idv);
                    } 
                    service.SaveChagnes();
                    return l;
                }
            }
        }

        public Guid NextGuid()
        {
            return Guid.NewGuid();
        }
        public string NextGuidStr()
        {
            return Guid.NewGuid().ToString("N").ToLower();
        }
        public async Task StartAsnyc()
        {
           



        }



        public   DateTime LongIDToDate(long id)
        {
            var id2 = id >> 22;
            var d = worker.firestDate.AddMilliseconds(id2) ;
            return d;
        }
        public   long DateToLongID(DateTime dt)
        {
            var l = ((long)(dt.ToUniversalTime() - worker.firestDate).TotalMilliseconds) << 22;
            return l;
        }

        public int GetOrder() => 0; //display first
    }
}
